{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Calysto Processing\n",
    "\n",
    "This notebook shows Calysto Processing, a MetaKernel-based Jupyter language.\n",
    "\n",
    "To see this notebook with included Javascript parts, please use this URL:\n",
    "\n",
    "http://nbviewer.ipython.org/github/Calysto/metakernel/blob/master/examples/Calysto%20Processing.ipynb\n",
    "\n",
    "To run Calysto Processing yourself, you will need:\n",
    "\n",
    "* IPython/Jupyter\n",
    "* MetaKernel\n",
    "* Calysto\n",
    "* Calysto Processing\n",
    "\n",
    "You can run any Processing sketch as a cell in a notebook:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\n",
       "        var component = document.getElementById(\"sketch_1\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        component = document.getElementById(\"state_1\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        component = document.getElementById(\"controls_div_1\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        require([window.location.protocol + \"//calysto.github.io/javascripts/processing/processing.js\"], function() {\n",
       "            // FIXME: Stop all previously running versions (?)\n",
       "            var processingInstance = Processing.getInstanceById(\"canvas_1\");\n",
       "            if (processingInstance != undefined && processingInstance.isRunning())\n",
       "                processingInstance.noLoop();\n",
       "        });\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"canvas_div_1\">\n",
       "  <b>Sketch #1:</b><br/>\n",
       "  <canvas id=\"canvas_1\"></canvas><br/>\n",
       "</div>\n",
       "<div id=\"controls_div_1\">\n",
       "  <button id=\"run_button_1\" onclick=\"startSketch('1');\">\n",
       "    <i class=\"fa fa-play-circle-o\" style=\"size: 2em;\"></i>\n",
       "        Run\n",
       "  </button>\n",
       "  <button id=\"pause_button_1\" onclick=\"pauseSketch('1');\">\n",
       "    <i class=\"fa fa-pause\" style=\"size: 2em;\"></i>\n",
       "        Pause\n",
       "  </button>\n",
       "  <button id=\"setup_button_1\" onclick=\"setupSketch('1');\">\n",
       "    setup()\n",
       "  </button>\n",
       "  <button id=\"draw_button_1\" onclick=\"drawSketch('1');\">\n",
       "    draw()\n",
       "  </button>\n",
       "</div>\n",
       "<b>Sketch #1 state:</b> <span id=\"state_1\">Loading...</span><br/>\n",
       "<script>\n",
       "\n",
       "function change_button(button, disable) {\n",
       "    button.disabled = disable;\n",
       "    if (disable) {\n",
       "        button.style.color = \"grey\";\n",
       "    } else {\n",
       "        button.style.color = \"black\";\n",
       "    }\n",
       "}\n",
       "\n",
       "function startSketch(id) {\n",
       "    switchSketchState(id, true);\n",
       "}\n",
       "\n",
       "function pauseSketch(id) {\n",
       "    switchSketchState(id, false);\n",
       "}\n",
       "\n",
       "function drawSketch(id) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (processingInstance != undefined) {\n",
       "        if (processingInstance.draw != undefined) {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"Drawing...\";\n",
       "            try {\n",
       "                processingInstance.redraw();\n",
       "                document.getElementById(\"state_\" + id).innerHTML = \"Drawing... done! Paused.\";\n",
       "                document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "            } catch (e) {\n",
       "                processingInstance.println(e.toString());\n",
       "                document.getElementById(\"state_\" + id).innerHTML = e.toString();\n",
       "                document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "            }\n",
       "        } else {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"No drawing() function. Paused.\";\n",
       "            document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Error.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "    }\n",
       "    change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "    change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "    change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "    change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "}\n",
       "\n",
       "function setupSketch(id) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (processingInstance != undefined) {\n",
       "        if (processingInstance.setup != undefined) {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"Setting up...\";\n",
       "            try {\n",
       "                processingInstance.setup();\n",
       "                document.getElementById(\"state_\" + id).innerHTML = \"Setting up... done! Paused.\";\n",
       "                document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "            } catch (e) {\n",
       "                processingInstance.println(e.toString());\n",
       "                document.getElementById(\"state_\" + id).innerHTML = e.toString();\n",
       "                document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "            }\n",
       "        } else {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"No setup() function. Paused.\";\n",
       "            document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Error.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "    }\n",
       "    change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "    change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "    change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "    change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "}\n",
       "\n",
       "function switchSketchState(id, on) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (on) {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Running...\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"green\";\n",
       "        change_button(document.getElementById(\"run_button_\" + id), true);\n",
       "        change_button(document.getElementById(\"pause_button_\" + id), processingInstance.draw == undefined);\n",
       "        change_button(document.getElementById(\"setup_button_\" + id),  true);\n",
       "        change_button(document.getElementById(\"draw_button_\" + id), true);\n",
       "        processingInstance.loop();  // call Processing loop() function\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Paused.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "        change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "        change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "        change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "        processingInstance.noLoop(); // stop animation, call noLoop()\n",
       "    }\n",
       "}\n",
       "\n",
       "require([window.location.protocol + \"//calysto.github.io/javascripts/processing/processing.js\"], function () {\n",
       "    var processingCode = 'line(10, 10, 90, 90);';\n",
       "    var cc;\n",
       "    var processingInstance;\n",
       "    var has_error = false;\n",
       "    try {\n",
       "        cc = Processing.compile(processingCode);\n",
       "    } catch (e) {\n",
       "        console.log(e);\n",
       "        cc = Processing.compile(\"println('\" + e.toString() + \"');\");\n",
       "        document.getElementById(\"state_1\").innerHTML = e.toString();\n",
       "        document.getElementById(\"state_1\").style.color = \"red\";\n",
       "        has_error = true;\n",
       "    }\n",
       "    if (cc != undefined) {\n",
       "        try {\n",
       "            processingInstance = new Processing(\"canvas_1\", cc);\n",
       "        } catch (e) {\n",
       "            console.log(e);\n",
       "            cc = Processing.compile(\"println('\" + e.toString() + \"');\");\n",
       "            document.getElementById(\"state_1\").innerHTML = e.toString();\n",
       "            document.getElementById(\"state_1\").style.color = \"red\";\n",
       "            processingInstance = new Processing(\"canvas_1\", cc);\n",
       "            has_error = true;\n",
       "        }\n",
       "    }\n",
       "    if (processingInstance != undefined) {\n",
       "        setTimeout(function () {\n",
       "            // Canvas:\n",
       "            if (processingInstance.externals.context === undefined) {\n",
       "                document.getElementById(\"canvas_div_1\").style.display = \"none\";\n",
       "            }\n",
       "        }, 100);\n",
       "        // Controls:\n",
       "        if (!(processingInstance.isRunning() && processingInstance.draw != undefined)) {\n",
       "            document.getElementById(\"controls_div_1\").style.display = \"none\";\n",
       "        }\n",
       "        if (processingInstance.draw != undefined) {\n",
       "            if (!has_error) {\n",
       "                document.getElementById(\"state_1\").innerHTML = \"Running...\";\n",
       "                document.getElementById(\"state_1\").style.color = \"green\";\n",
       "            }\n",
       "            change_button(document.getElementById(\"run_button_1\"), true);\n",
       "            change_button(document.getElementById(\"pause_button_1\"), false);\n",
       "            change_button(document.getElementById(\"setup_button_1\"),  true);\n",
       "            change_button(document.getElementById(\"draw_button_1\"), true);\n",
       "        } else {\n",
       "            if (!has_error) {\n",
       "                document.getElementById(\"state_1\").innerHTML = \"Done.\";\n",
       "                document.getElementById(\"state_1\").style.color = \"blue\";\n",
       "            }\n",
       "            change_button(document.getElementById(\"run_button_1\"), true);\n",
       "            change_button(document.getElementById(\"pause_button_1\"), true);\n",
       "            change_button(document.getElementById(\"setup_button_1\"),  processingInstance.setup == undefined);\n",
       "            change_button(document.getElementById(\"draw_button_1\"), true);\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"canvas_div_1\").style.display = \"none\";\n",
       "        document.getElementById(\"controls_div_1\").style.display = \"none\";\n",
       "        if (!has_error) {\n",
       "            document.getElementById(\"state_1\").innerHTML = \"Error.\";\n",
       "            document.getElementById(\"state_1\").style.color = \"red\";\n",
       "        }\n",
       "        change_button(document.getElementById(\"run_button_1\"), true);\n",
       "        change_button(document.getElementById(\"pause_button_1\"), true);\n",
       "        change_button(document.getElementById(\"setup_button_1\"),  true);\n",
       "        change_button(document.getElementById(\"draw_button_1\"), true);\n",
       "    }\n",
       "});\n",
       "\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "line(10, 10, 90, 90);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Calysto Processing has full error checking and messages. It shows the line both in red, and highlights in yellow the offending line:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      " Line     +---------------------------------------------------------------------------\n",
      "    1: -> | line(10, 10, 90, h);\n",
      "          +---------------------------------------------------------------------------\n",
      "\n",
      "Compile error in line 1: Cannot find anything named “h”\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<style type=\"text/css\">\n",
       "      .styled-background { background-color: #ff7; }\n",
       "</style>\n",
       "\n",
       "<script>\n",
       "if (typeof markedText !== 'undefined') {\n",
       "        markedText.clear();\n",
       "}\n",
       "IPython.notebook.select_prev()\n",
       "var cell = IPython.notebook.get_selected_cell();\n",
       "markedText = cell.code_mirror.markText({line: -1, col: 0},\n",
       "                                       {line: 0, col: 0},\n",
       "                                       {className: \"styled-background\"});\n",
       "cell.show_line_numbers(1)\n",
       "IPython.notebook.select_next()\n",
       "</script>\n",
       "                    "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "line(10, 10, 90, h);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Processing sketches that use setup and draw can be stepped one call at a time. Simply Pause the sketch, and press the setup() or draw() buttons. Press on the Run button to resume:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\n",
       "        var component = document.getElementById(\"sketch_3\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        component = document.getElementById(\"state_3\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        component = document.getElementById(\"controls_div_3\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        require([window.location.protocol + \"//calysto.github.io/javascripts/processing/processing.js\"], function() {\n",
       "            // FIXME: Stop all previously running versions (?)\n",
       "            var processingInstance = Processing.getInstanceById(\"canvas_3\");\n",
       "            if (processingInstance != undefined && processingInstance.isRunning())\n",
       "                processingInstance.noLoop();\n",
       "        });\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"canvas_div_3\">\n",
       "  <b>Sketch #3:</b><br/>\n",
       "  <canvas id=\"canvas_3\"></canvas><br/>\n",
       "</div>\n",
       "<div id=\"controls_div_3\">\n",
       "  <button id=\"run_button_3\" onclick=\"startSketch('3');\">\n",
       "    <i class=\"fa fa-play-circle-o\" style=\"size: 2em;\"></i>\n",
       "        Run\n",
       "  </button>\n",
       "  <button id=\"pause_button_3\" onclick=\"pauseSketch('3');\">\n",
       "    <i class=\"fa fa-pause\" style=\"size: 2em;\"></i>\n",
       "        Pause\n",
       "  </button>\n",
       "  <button id=\"setup_button_3\" onclick=\"setupSketch('3');\">\n",
       "    setup()\n",
       "  </button>\n",
       "  <button id=\"draw_button_3\" onclick=\"drawSketch('3');\">\n",
       "    draw()\n",
       "  </button>\n",
       "</div>\n",
       "<b>Sketch #3 state:</b> <span id=\"state_3\">Loading...</span><br/>\n",
       "<script>\n",
       "\n",
       "function change_button(button, disable) {\n",
       "    button.disabled = disable;\n",
       "    if (disable) {\n",
       "        button.style.color = \"grey\";\n",
       "    } else {\n",
       "        button.style.color = \"black\";\n",
       "    }\n",
       "}\n",
       "\n",
       "function startSketch(id) {\n",
       "    switchSketchState(id, true);\n",
       "}\n",
       "\n",
       "function pauseSketch(id) {\n",
       "    switchSketchState(id, false);\n",
       "}\n",
       "\n",
       "function drawSketch(id) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (processingInstance != undefined) {\n",
       "        if (processingInstance.draw != undefined) {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"Drawing...\";\n",
       "            try {\n",
       "                processingInstance.redraw();\n",
       "                document.getElementById(\"state_\" + id).innerHTML = \"Drawing... done! Paused.\";\n",
       "                document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "            } catch (e) {\n",
       "                processingInstance.println(e.toString());\n",
       "                document.getElementById(\"state_\" + id).innerHTML = e.toString();\n",
       "                document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "            }\n",
       "        } else {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"No drawing() function. Paused.\";\n",
       "            document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Error.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "    }\n",
       "    change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "    change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "    change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "    change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "}\n",
       "\n",
       "function setupSketch(id) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (processingInstance != undefined) {\n",
       "        if (processingInstance.setup != undefined) {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"Setting up...\";\n",
       "            try {\n",
       "                processingInstance.setup();\n",
       "                document.getElementById(\"state_\" + id).innerHTML = \"Setting up... done! Paused.\";\n",
       "                document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "            } catch (e) {\n",
       "                processingInstance.println(e.toString());\n",
       "                document.getElementById(\"state_\" + id).innerHTML = e.toString();\n",
       "                document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "            }\n",
       "        } else {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"No setup() function. Paused.\";\n",
       "            document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Error.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "    }\n",
       "    change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "    change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "    change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "    change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "}\n",
       "\n",
       "function switchSketchState(id, on) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (on) {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Running...\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"green\";\n",
       "        change_button(document.getElementById(\"run_button_\" + id), true);\n",
       "        change_button(document.getElementById(\"pause_button_\" + id), processingInstance.draw == undefined);\n",
       "        change_button(document.getElementById(\"setup_button_\" + id),  true);\n",
       "        change_button(document.getElementById(\"draw_button_\" + id), true);\n",
       "        processingInstance.loop();  // call Processing loop() function\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Paused.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "        change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "        change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "        change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "        processingInstance.noLoop(); // stop animation, call noLoop()\n",
       "    }\n",
       "}\n",
       "\n",
       "require([window.location.protocol + \"//calysto.github.io/javascripts/processing/processing.js\"], function () {\n",
       "    var processingCode = 'void setup() {\\n    background(255);\\n}\\n\\nvoid draw() {\\n    ellipse(mouseX, mouseY, 5, 5);\\n}';\n",
       "    var cc;\n",
       "    var processingInstance;\n",
       "    var has_error = false;\n",
       "    try {\n",
       "        cc = Processing.compile(processingCode);\n",
       "    } catch (e) {\n",
       "        console.log(e);\n",
       "        cc = Processing.compile(\"println('\" + e.toString() + \"');\");\n",
       "        document.getElementById(\"state_3\").innerHTML = e.toString();\n",
       "        document.getElementById(\"state_3\").style.color = \"red\";\n",
       "        has_error = true;\n",
       "    }\n",
       "    if (cc != undefined) {\n",
       "        try {\n",
       "            processingInstance = new Processing(\"canvas_3\", cc);\n",
       "        } catch (e) {\n",
       "            console.log(e);\n",
       "            cc = Processing.compile(\"println('\" + e.toString() + \"');\");\n",
       "            document.getElementById(\"state_3\").innerHTML = e.toString();\n",
       "            document.getElementById(\"state_3\").style.color = \"red\";\n",
       "            processingInstance = new Processing(\"canvas_3\", cc);\n",
       "            has_error = true;\n",
       "        }\n",
       "    }\n",
       "    if (processingInstance != undefined) {\n",
       "        setTimeout(function () {\n",
       "            // Canvas:\n",
       "            if (processingInstance.externals.context === undefined) {\n",
       "                document.getElementById(\"canvas_div_3\").style.display = \"none\";\n",
       "            }\n",
       "        }, 100);\n",
       "        // Controls:\n",
       "        if (!(processingInstance.isRunning() && processingInstance.draw != undefined)) {\n",
       "            document.getElementById(\"controls_div_3\").style.display = \"none\";\n",
       "        }\n",
       "        if (processingInstance.draw != undefined) {\n",
       "            if (!has_error) {\n",
       "                document.getElementById(\"state_3\").innerHTML = \"Running...\";\n",
       "                document.getElementById(\"state_3\").style.color = \"green\";\n",
       "            }\n",
       "            change_button(document.getElementById(\"run_button_3\"), true);\n",
       "            change_button(document.getElementById(\"pause_button_3\"), false);\n",
       "            change_button(document.getElementById(\"setup_button_3\"),  true);\n",
       "            change_button(document.getElementById(\"draw_button_3\"), true);\n",
       "        } else {\n",
       "            if (!has_error) {\n",
       "                document.getElementById(\"state_3\").innerHTML = \"Done.\";\n",
       "                document.getElementById(\"state_3\").style.color = \"blue\";\n",
       "            }\n",
       "            change_button(document.getElementById(\"run_button_3\"), true);\n",
       "            change_button(document.getElementById(\"pause_button_3\"), true);\n",
       "            change_button(document.getElementById(\"setup_button_3\"),  processingInstance.setup == undefined);\n",
       "            change_button(document.getElementById(\"draw_button_3\"), true);\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"canvas_div_3\").style.display = \"none\";\n",
       "        document.getElementById(\"controls_div_3\").style.display = \"none\";\n",
       "        if (!has_error) {\n",
       "            document.getElementById(\"state_3\").innerHTML = \"Error.\";\n",
       "            document.getElementById(\"state_3\").style.color = \"red\";\n",
       "        }\n",
       "        change_button(document.getElementById(\"run_button_3\"), true);\n",
       "        change_button(document.getElementById(\"pause_button_3\"), true);\n",
       "        change_button(document.getElementById(\"setup_button_3\"),  true);\n",
       "        change_button(document.getElementById(\"draw_button_3\"), true);\n",
       "    }\n",
       "});\n",
       "\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "void setup() {\n",
    "    background(255);\n",
    "}\n",
    "\n",
    "void draw() {\n",
    "    ellipse(mouseX, mouseY, 5, 5);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are a number of additional support tools for Java and Processing in Calysto Processing, including the online tutor:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "        <iframe\n",
       "            width=\"100%\"\n",
       "            height=\"500\"\n",
       "            src=\"https://pythontutor.com/iframe-embed.html#code=%0Apublic%20class%20YourClassNameHere%20%7B%0A%20%20%20%20public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%20%20%20%20%20%20%20%20for%20%28int%20i%3D0%3B%20i%20%3C%2010%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.println%28%22i%3A%20%22%20%2B%20i%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D&origin=opt-frontend.js&cumulative=false&heapPrimitives=false&textReferences=false&py=java&rawInputLstJSON=%5B%5D&curInstr=0&codeDivWidth=350&codeDivHeight=400\"\n",
       "            frameborder=\"0\"\n",
       "            allowfullscreen\n",
       "        ></iframe>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.lib.display.IFrame object at 0x7f5f71705550>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%tutor\n",
    "\n",
    "public class YourClassNameHere {\n",
    "    public static void main(String[] args) {\n",
    "        for (int i=0; i < 10; i++) {\n",
    "            System.out.println(\"i: \" + i);\n",
    "        }\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And drag-and-drop Processing code generator, called Jigsaw:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\n",
       "    if (document.jigsaw_register_workspace === undefined) {\n",
       "\n",
       "        document.jigsaw_workspaces = {};\n",
       "\n",
       "        document.jigsaw_register_workspace = function(workspace_filename, workspace, xml_init) {\n",
       "            workspace.element = document.element;\n",
       "            document.jigsaw_workspaces[workspace_filename] = workspace;\n",
       "\n",
       "            try {\n",
       "                $([window.parent.IPython.events]).on('notebook_saved.Notebook', function() { \n",
       "                    try {\n",
       "                        document.jigsaw_save_workspace(workspace_filename); \n",
       "                    } catch(err) {\n",
       "                        // ignore failure, might not exist\n",
       "                    }\n",
       "                });\n",
       "            } catch (err) {\n",
       "                // rendering for display\n",
       "            }\n",
       "            \n",
       "            var xml = document.jigsaw_loadXMLDoc(workspace_filename);\n",
       "            if (xml === null) {\n",
       "                xml = xml_init;\n",
       "                if (xml === null) {\n",
       "                    xml = Blockly.Xml.textToDom('<xml id=\"workspace\"></xml>');\n",
       "                }\n",
       "            } else {\n",
       "                xml = xml.children[0]; // document\n",
       "            }\n",
       "            Blockly.Xml.domToWorkspace(workspace, xml);\n",
       "        };\n",
       "\n",
       "        document.jigsaw_handle_output = function(workspace_filename, out) {\n",
       "            var workspace = document.jigsaw_workspaces[workspace_filename];\n",
       "            //var output_area = workspace.element.output_area;\n",
       "            var cell_index = document.jigsaw_get_cell(workspace.element);\n",
       "            var cell = IPython.notebook.get_cell(cell_index);\n",
       "            var res = null;\n",
       "            var data = null;\n",
       "            document.cell = cell;\n",
       "            document.out = out;\n",
       "            if (out.msg_type == \"stream\") {\n",
       "                res = out.content.text;\n",
       "                //document.getElementById('code_output').value += res.toString();\n",
       "            } else if (out.msg_type === \"pyout\") {\n",
       "                // if output is a python object\n",
       "                res = out.content.data[\"text/plain\"];\n",
       "                //document.getElementById('code_output').value += res.toString(); \n",
       "            } else if (out.msg_type == \"pyerr\") {\n",
       "                // if output is a python error\n",
       "                res = out.content.data[\"text/plain\"];\n",
       "                //document.getElementById('code_output').value += res.toString();\n",
       "            } else if (out.msg_type == \"execute_result\") {\n",
       "                var str = out.content.data[\"text/plain\"];\n",
       "                res = str;\n",
       "                if (res.indexOf(\"u\") == 0)\n",
       "                    res = res.substring(2, res.length - 1) + \"\\n\";\n",
       "                if (res) {\n",
       "                    //document.getElementById('code_output').value += res.toString();\n",
       "                }\n",
       "            } else if (out.msg_type == \"error\") {\n",
       "                res = out.content.ename + \": \" + out.content.evalue + \"\\n\";\n",
       "                // FIXME: out.traceback is Array of terminal color-coded [-codes\n",
       "            } else {\n",
       "                // if output is something we haven't thought of\n",
       "                res = out.toString();\n",
       "                //document.getElementById('code_output').value += res.toString();\n",
       "            }\n",
       "            if (res) {\n",
       "                cell.output_area.append_output({output_type: \"stream\", text: res.toString(), name: \"output\"});\n",
       "            }\n",
       "        };\n",
       "        \n",
       "        document.jigsaw_generate = function(workspace_filename, language, insert_code) {\n",
       "            var workspace = document.jigsaw_workspaces[workspace_filename];\n",
       "            var callbacks = { 'iopub' : {'output' : function(out) { document.jigsaw_handle_output(workspace_filename, out); }}};\n",
       "            var code = Blockly[language].workspaceToCode(workspace);\n",
       "            if (insert_code == 1) {\n",
       "                var cell_index = document.jigsaw_get_cell(workspace.element);\n",
       "                var cell = IPython.notebook.insert_cell_at_index(0, cell_index + 1);\n",
       "                cell.set_text(code);\n",
       "            } else {\n",
       "                window.parent.IPython.notebook.kernel.execute(code,\n",
       "                                                              callbacks,\n",
       "                                                              {silent: false});\n",
       "            }\n",
       "        };\n",
       "        \n",
       "        document.jigsaw_save_workspace = function(workspace_filename) {\n",
       "            var workspace = document.jigsaw_workspaces[workspace_filename];\n",
       "            var xml = Blockly.Xml.workspaceToDom(workspace);\n",
       "            document.xml = xml;\n",
       "            if (xml !== undefined) {\n",
       "                console.log(xml);\n",
       "                //xml.style = \"display: none\";\n",
       "                //xml.id = \"workspace\";\n",
       "                var xml_text = Blockly.Xml.domToText(xml)\n",
       "                IPython.notebook.kernel.execute('%%file ' + workspace_filename + '\\n' + xml_text);\n",
       "            }\n",
       "        };\n",
       "        \n",
       "        document.jigsaw_loadXMLDoc = function(filename) {\n",
       "            var xhttp = new XMLHttpRequest();\n",
       "            xhttp.open(\"GET\", filename, false);\n",
       "            xhttp.send();\n",
       "            return xhttp.responseXML;\n",
       "        };\n",
       "    }\n",
       "\n",
       "    document.jigsaw_get_cell = function (element) {\n",
       "        // FIXME: brittle and ugly:\n",
       "        var mydiv = element[0].parentNode.parentNode.parentNode.parentNode;\n",
       "        var cells = IPython.notebook.get_cells();\n",
       "        for (var i = 0; i < cells.length; i++) {\n",
       "            if (mydiv === cells[i].element[0]) {\n",
       "                return i;\n",
       "            }\n",
       "        }\n",
       "        return null;\n",
       "    };\n",
       "\n",
       "    document.jigsaw_clear_output = function (workspace_filename) {\n",
       "        var workspace = document.jigsaw_workspaces[workspace_filename];\n",
       "        var cell_index = document.jigsaw_get_cell(workspace.element);\n",
       "        var cell = IPython.notebook.get_cell(cell_index);\n",
       "        // FIXME: brittle and ugly:\n",
       "        cell.element[0].children[2].children[1].children[2].children[1].children[0].innerHTML = \"\"\n",
       "        cell.output_area.outputs[2].text = \"\"\n",
       "    };\n",
       "\n",
       "    try {\n",
       "        document.element = element;\n",
       "    } catch (err) {\n",
       "        // rendering\n",
       "    }\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<iframe src=\"processing1.html\" width=\"100%\" height=\"350\" style=\"resize: both; overflow: auto;\"></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%jigsaw Processing --workspace processing1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Clicking on \"Generate Processing Code\" created the following cell (except for a type that we added):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\n",
       "        var component = document.getElementById(\"sketch_7\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        component = document.getElementById(\"state_7\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        component = document.getElementById(\"controls_div_7\");\n",
       "        if (component != undefined)\n",
       "            component.remove();\n",
       "        require([window.location.protocol + \"//calysto.github.io/javascripts/processing/processing.js\"], function() {\n",
       "            // FIXME: Stop all previously running versions (?)\n",
       "            var processingInstance = Processing.getInstanceById(\"canvas_7\");\n",
       "            if (processingInstance != undefined && processingInstance.isRunning())\n",
       "                processingInstance.noLoop();\n",
       "        });\n",
       "        "
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"canvas_div_7\">\n",
       "  <b>Sketch #7:</b><br/>\n",
       "  <canvas id=\"canvas_7\"></canvas><br/>\n",
       "</div>\n",
       "<div id=\"controls_div_7\">\n",
       "  <button id=\"run_button_7\" onclick=\"startSketch('7');\">\n",
       "    <i class=\"fa fa-play-circle-o\" style=\"size: 2em;\"></i>\n",
       "        Run\n",
       "  </button>\n",
       "  <button id=\"pause_button_7\" onclick=\"pauseSketch('7');\">\n",
       "    <i class=\"fa fa-pause\" style=\"size: 2em;\"></i>\n",
       "        Pause\n",
       "  </button>\n",
       "  <button id=\"setup_button_7\" onclick=\"setupSketch('7');\">\n",
       "    setup()\n",
       "  </button>\n",
       "  <button id=\"draw_button_7\" onclick=\"drawSketch('7');\">\n",
       "    draw()\n",
       "  </button>\n",
       "</div>\n",
       "<b>Sketch #7 state:</b> <span id=\"state_7\">Loading...</span><br/>\n",
       "<script>\n",
       "\n",
       "function change_button(button, disable) {\n",
       "    button.disabled = disable;\n",
       "    if (disable) {\n",
       "        button.style.color = \"grey\";\n",
       "    } else {\n",
       "        button.style.color = \"black\";\n",
       "    }\n",
       "}\n",
       "\n",
       "function startSketch(id) {\n",
       "    switchSketchState(id, true);\n",
       "}\n",
       "\n",
       "function pauseSketch(id) {\n",
       "    switchSketchState(id, false);\n",
       "}\n",
       "\n",
       "function drawSketch(id) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (processingInstance != undefined) {\n",
       "        if (processingInstance.draw != undefined) {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"Drawing...\";\n",
       "            try {\n",
       "                processingInstance.redraw();\n",
       "                document.getElementById(\"state_\" + id).innerHTML = \"Drawing... done! Paused.\";\n",
       "                document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "            } catch (e) {\n",
       "                processingInstance.println(e.toString());\n",
       "                document.getElementById(\"state_\" + id).innerHTML = e.toString();\n",
       "                document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "            }\n",
       "        } else {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"No drawing() function. Paused.\";\n",
       "            document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Error.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "    }\n",
       "    change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "    change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "    change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "    change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "}\n",
       "\n",
       "function setupSketch(id) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (processingInstance != undefined) {\n",
       "        if (processingInstance.setup != undefined) {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"Setting up...\";\n",
       "            try {\n",
       "                processingInstance.setup();\n",
       "                document.getElementById(\"state_\" + id).innerHTML = \"Setting up... done! Paused.\";\n",
       "                document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "            } catch (e) {\n",
       "                processingInstance.println(e.toString());\n",
       "                document.getElementById(\"state_\" + id).innerHTML = e.toString();\n",
       "                document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "            }\n",
       "        } else {\n",
       "            document.getElementById(\"state_\" + id).innerHTML = \"No setup() function. Paused.\";\n",
       "            document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Error.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"red\";\n",
       "    }\n",
       "    change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "    change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "    change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "    change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "}\n",
       "\n",
       "function switchSketchState(id, on) {\n",
       "    var processingInstance = Processing.getInstanceById(\"canvas_\" + id);\n",
       "    if (on) {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Running...\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"green\";\n",
       "        change_button(document.getElementById(\"run_button_\" + id), true);\n",
       "        change_button(document.getElementById(\"pause_button_\" + id), processingInstance.draw == undefined);\n",
       "        change_button(document.getElementById(\"setup_button_\" + id),  true);\n",
       "        change_button(document.getElementById(\"draw_button_\" + id), true);\n",
       "        processingInstance.loop();  // call Processing loop() function\n",
       "    } else {\n",
       "        document.getElementById(\"state_\" + id).innerHTML = \"Paused.\";\n",
       "        document.getElementById(\"state_\" + id).style.color = \"blue\";\n",
       "        change_button(document.getElementById(\"run_button_\" + id), processingInstance.draw == undefined);\n",
       "        change_button(document.getElementById(\"pause_button_\" + id), true);\n",
       "        change_button(document.getElementById(\"setup_button_\" + id), processingInstance.setup == undefined);\n",
       "        change_button(document.getElementById(\"draw_button_\" + id), processingInstance.draw == undefined);\n",
       "        processingInstance.noLoop(); // stop animation, call noLoop()\n",
       "    }\n",
       "}\n",
       "\n",
       "require([window.location.protocol + \"//calysto.github.io/javascripts/processing/processing.js\"], function () {\n",
       "    var processingCode = '\\n\\nvoid draw() {\\n    for (int i = 1; i<=10; i++) {\\n        ellipse((30 * i), 10, 20, 20);\\n    }\\n}\\n\\nvoid setup() {\\n    size(600, 40);\\n}\\n\\n';\n",
       "    var cc;\n",
       "    var processingInstance;\n",
       "    var has_error = false;\n",
       "    try {\n",
       "        cc = Processing.compile(processingCode);\n",
       "    } catch (e) {\n",
       "        console.log(e);\n",
       "        cc = Processing.compile(\"println('\" + e.toString() + \"');\");\n",
       "        document.getElementById(\"state_7\").innerHTML = e.toString();\n",
       "        document.getElementById(\"state_7\").style.color = \"red\";\n",
       "        has_error = true;\n",
       "    }\n",
       "    if (cc != undefined) {\n",
       "        try {\n",
       "            processingInstance = new Processing(\"canvas_7\", cc);\n",
       "        } catch (e) {\n",
       "            console.log(e);\n",
       "            cc = Processing.compile(\"println('\" + e.toString() + \"');\");\n",
       "            document.getElementById(\"state_7\").innerHTML = e.toString();\n",
       "            document.getElementById(\"state_7\").style.color = \"red\";\n",
       "            processingInstance = new Processing(\"canvas_7\", cc);\n",
       "            has_error = true;\n",
       "        }\n",
       "    }\n",
       "    if (processingInstance != undefined) {\n",
       "        setTimeout(function () {\n",
       "            // Canvas:\n",
       "            if (processingInstance.externals.context === undefined) {\n",
       "                document.getElementById(\"canvas_div_7\").style.display = \"none\";\n",
       "            }\n",
       "        }, 100);\n",
       "        // Controls:\n",
       "        if (!(processingInstance.isRunning() && processingInstance.draw != undefined)) {\n",
       "            document.getElementById(\"controls_div_7\").style.display = \"none\";\n",
       "        }\n",
       "        if (processingInstance.draw != undefined) {\n",
       "            if (!has_error) {\n",
       "                document.getElementById(\"state_7\").innerHTML = \"Running...\";\n",
       "                document.getElementById(\"state_7\").style.color = \"green\";\n",
       "            }\n",
       "            change_button(document.getElementById(\"run_button_7\"), true);\n",
       "            change_button(document.getElementById(\"pause_button_7\"), false);\n",
       "            change_button(document.getElementById(\"setup_button_7\"),  true);\n",
       "            change_button(document.getElementById(\"draw_button_7\"), true);\n",
       "        } else {\n",
       "            if (!has_error) {\n",
       "                document.getElementById(\"state_7\").innerHTML = \"Done.\";\n",
       "                document.getElementById(\"state_7\").style.color = \"blue\";\n",
       "            }\n",
       "            change_button(document.getElementById(\"run_button_7\"), true);\n",
       "            change_button(document.getElementById(\"pause_button_7\"), true);\n",
       "            change_button(document.getElementById(\"setup_button_7\"),  processingInstance.setup == undefined);\n",
       "            change_button(document.getElementById(\"draw_button_7\"), true);\n",
       "        }\n",
       "    } else {\n",
       "        document.getElementById(\"canvas_div_7\").style.display = \"none\";\n",
       "        document.getElementById(\"controls_div_7\").style.display = \"none\";\n",
       "        if (!has_error) {\n",
       "            document.getElementById(\"state_7\").innerHTML = \"Error.\";\n",
       "            document.getElementById(\"state_7\").style.color = \"red\";\n",
       "        }\n",
       "        change_button(document.getElementById(\"run_button_7\"), true);\n",
       "        change_button(document.getElementById(\"pause_button_7\"), true);\n",
       "        change_button(document.getElementById(\"setup_button_7\"),  true);\n",
       "        change_button(document.getElementById(\"draw_button_7\"), true);\n",
       "    }\n",
       "});\n",
       "\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "\n",
    "void draw() {\n",
    "    for (int i = 1; i<=10; i++) {\n",
    "        ellipse((30 * i), 10, 20, 20);\n",
    "    }\n",
    "}\n",
    "\n",
    "void setup() {\n",
    "    size(600, 40);\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Try it out!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Calysto Processing",
   "language": "java",
   "name": "calysto_processing"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "text/x-java",
    "version": 2
   },
   "file_extension": ".java",
   "mimetype": "text/x-java",
   "name": "java"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
